#include "struct.h"
#define SET_BYTE(vbyte, index) ((vbyte) |= (1 << ((index) ^ 7)))
#define CLR_BYTE(vbyte, index) ((vbyte) &= (~(1 << ((index) ^ 7))))

char *getName(char *name) {
    int i = 0, len = strlen(name);
    char *temp = (char *)calloc(sizeof(char), len);
    for( i; i < len; i++ ) {
        if(name[i] != '.') {
            temp[i] = name[i];
        } else {
            break;
        }
    }
    return temp;
}

char *getFinal(char *name) {
    int i = 0, len = strlen(name), dir = 0, index = 0;
    char *final = (char *)calloc(sizeof(char), 3);
    for( i; i < len; i++ ) {
        if(name[i] == '.') {
            dir = 1;
            continue;
            i = 0;
        }
        if( dir != 0 ) {
            final[index] = name[i];
            index++;
        }
    }
    return final;
}

int getLastBit(CODING *p, int val) {
    int sum = 0;
    int i;

    for( i = 0; i < val; i++ ) {
        sum += strlen((p + i)->code) * ((p + i)->charFreq.freq);
        sum &= 0xFF;
    }
	sum &= 0x7;
	return sum == 0 ? 8 : sum;
}

void zip(CODING *p, char *hash[], char *filename, int variety, TEXT *charFreq) {
    FILE *fp = fopen(filename,"rb");
    int i = 0;
    char *name = getName(filename), *final = getFinal(filename);
    strcat(name, ".huf");
    FILE *tar = fopen(name, "wb");
    HEAD fileHead;
    for( i = 0; i < 3; i++ ) {
        fileHead.flag[i] = final[i];
    }
    fileHead.variety = variety;
    fileHead.lastValueBit = getLastBit(p, variety);
    fwrite(&fileHead, sizeof(HEAD), 1, tar);
    fwrite(charFreq, sizeof(TEXT), variety, tar);
    int temp = 0;
    temp = fgetc(fp);
    int index = 0;
    char value;
    while(!feof(fp)) {
        for( i = 0; hash[temp][i]; i++ ) {
            if('0' == hash[temp][i]) {
                CLR_BYTE(value, index);
            } else {
                SET_BYTE(value, index);
            }
            index ++ ;
            if(index == 8) {
                index = 0;
                fwrite(&value, sizeof(unsigned char), 1, tar);
            }
        }
        temp = fgetc(fp);
    }
    if(index != 0) {
        fwrite(&value, sizeof(unsigned char), 1, tar);
    }
    printf("\n-----------------\nzip successfully!\n-----------------\n");
    fclose(fp);
    fclose(tar);
}
